package com.zrc.superframe_net.converter

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.zrc.superframe_net.converter.adapter.*
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Converter
import retrofit2.Retrofit
import java.lang.reflect.Type

/**
 * @Author: superman
 * @CreateTime: 7/28/21
 * @Describe:
 */
class CustomGsonConverterFactory private constructor(gson: Gson?) : Converter.Factory() {

    private val gson: Gson

    init {
        if (gson == null) {
            throw NullPointerException("gson == null")
        }
        this.gson = gson
    }

    override fun responseBodyConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<ResponseBody, *> {
        val adapter = gson.getAdapter(TypeToken.get(type))
        return CustomGsonResponseBodyConverter(gson, adapter)
    }

    override fun requestBodyConverter(
        type: Type,
        parameterAnnotations: Array<Annotation>,
        methodAnnotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, RequestBody> {
        val adapter = gson.getAdapter(TypeToken.get(type))
        return CustomGsonRequestBodyConverter(gson, adapter)
    }

    companion object {
        fun create(): CustomGsonConverterFactory {
            val gson = GsonBuilder()
                .registerTypeAdapter(Int::class.javaPrimitiveType, IntegerTypeAdapter())//int
                .registerTypeAdapter(Int::class.java, IntegerTypeAdapter())
                .registerTypeAdapter(Double::class.javaPrimitiveType, DoubleTypeAdapter())//double
                .registerTypeAdapter(Double::class.java, DoubleTypeAdapter())
                .registerTypeAdapter(Long::class.javaPrimitiveType, LongTypeAdapter())//long
                .registerTypeAdapter(Long::class.java, LongTypeAdapter())
                .registerTypeAdapter(Float::class.javaPrimitiveType, FloatTypeAdapter()) //float
                .registerTypeAdapter(Float::class.java, FloatTypeAdapter())
                .registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanTypeAdapter())//boolean
                .registerTypeAdapter(Boolean::class.java, BooleanTypeAdapter())
                .registerTypeAdapter(String::class.java, StringTypeAdapter())//string
                .create()
            return create(gson)
        }

        fun create(gson: Gson?): CustomGsonConverterFactory {
            return CustomGsonConverterFactory(gson)
        }
    }
}